#include "CoCoA/library.H"
#include <iostream>
#include <cstdlib>
#include <map>
using namespace CoCoA;
using namespace std;


static map<size_t, SparsePolyRing> __cocoa_rings;

const SparsePolyRing& create_ring(size_t i) {
		map<size_t, SparsePolyRing>::iterator pos = __cocoa_rings.find(i);
		if (pos != __cocoa_rings.end())
				return pos->second;
		else
		{
			pair< map<size_t, SparsePolyRing>::iterator, bool> res = __cocoa_rings.insert(make_pair(i,NewPolyRing(RingQ(), i)));
			return (res.first)->second;
		}

		/*
		try
		{
				return __cocoa_rings[i];
		}
		catch (...)
		{
			__cocoa_rings.insert(make_pair(i,SparsePolyRing(RingQ(), i)));
			return __cocoa_rings[i];
		}
		*/
}

class Wrapper {
		public:
				Wrapper(const RingElem& poly){
					__data=new RingElem(poly);
				}

				Wrapper(size_t Ri, size_t i){
					__data=new RingElem(indet(create_ring(Ri),i-1));
				}

				Wrapper(const Wrapper& w){
					__data=new RingElem(*((RingElem*) w.__data));
				}

				~Wrapper() {
					cout << "deleting RingElem ... " << endl;
					delete (RingElem*) __data;
				}

		void print() {
			cout << *(RingElem*)__data << endl;
		}

		private:
				void* __data;
};

CoCoA::GlobalManager CoCoAFoundations;

int main(){
	srand((unsigned long)&CoCoAFoundations);
	SparsePolyRing R = NewPolyRing(RingQ(), symbols("x","y"));
	RingElem p(R);
	Wrapper w(indet(R,1)), w1(2,2), w4(p),w5(p);
	w.print();
	w1.print();
	// delete p; error
	Wrapper w2(3,2), w3(3,3), w6(w3);
	w.print();
	w2.print();
	w3.print();
	w4.print();
	w5.print();
	w6.print();

	return 0;
}
